/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.sentry;

import java.net.URI;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * Dsn
 *
 * @since 2021-06-02
 **/
final class Dsn {
    private final @NotNull String projectId;
    private final @Nullable String path;
    private final @Nullable String secretKey;
    private final @NotNull String publicKey;
    private final @NotNull URI sentryUri;

    /*
    / The project ID which the authenticated user is bound to.
    */
    public @NotNull String getProjectId() {
        return projectId;
    }

    /*
    / An optional path of which Sentry is hosted
    */
    public @Nullable String getPath() {
        return path;
    }

    /*
    / The optional secret key to authenticate the SDK.
    */
    public @Nullable String getSecretKey() {
        return secretKey;
    }

    /*
    / The required public key to authenticate the SDK.
    */
    public @NotNull String getPublicKey() {
        return publicKey;
    }

    /*
    / The URI used to communicate with Sentry
    */
    @NotNull
    URI getSentryUri() {
        return sentryUri;
    }

    Dsn(@Nullable String dsn) throws IllegalArgumentException {
        try {
            URI uri = new URI(dsn).normalize();
            String userInfo = uri.getUserInfo();
            if (userInfo == null || userInfo.isEmpty()) {
                throw new IllegalArgumentException("Invalid DSN: No public key provided.");
            }
            String[] keys = userInfo.split(":", -1);
            publicKey = keys[0];
            if (publicKey == null || publicKey.isEmpty()) {
                throw new IllegalArgumentException("Invalid DSN: No public key provided.");
            }
            secretKey = keys.length > 1 ? keys[1] : null;
            String uriPath = uri.getPath();
            if (uriPath.endsWith(getSuffix())) {
                uriPath = uriPath.substring(0, uriPath.length() - 1);
            }
            int projectIdStart = uriPath.lastIndexOf(getSuffix()) + 1;
            String substring = uriPath.substring(0, projectIdStart);
            if (!substring.endsWith(getSuffix())) {
                substring += getSuffix();
            }
            this.path = substring;
            projectId = uriPath.substring(projectIdStart);
            if (projectId.isEmpty()) {
                throw new IllegalArgumentException("Invalid DSN: A Project Id is required.");
            }
            sentryUri =
                new URI(
                    uri.getScheme(),
                    null,
                    uri.getHost(),
                    uri.getPort(),
                    substring + "api/" + projectId,
                    null,
                    null);
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }

    @NotNull
    private String getSuffix() {
        return "/";
    }
}
